package com.example.tool.util.yto;

import cn.hutool.http.HttpRequest;
import cn.hutool.http.HttpResponse;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import org.apache.commons.codec.binary.Base64;
import org.apache.commons.codec.digest.DigestUtils;

import java.util.HashMap;
import java.util.Map;
import java.util.regex.Pattern;

public class YtoApiUtil {

/*    private static final String SECRET_KEY = "123456";
    private static final String METHOD = "track_query_adapter";
    private static final String VERSION = "v1";
    private static final String API_URL = "https://openuat.yto56test.com:6443/open/track_query_adapter/v1/RVIz3j/TEST";*/
    private static final String clientId = "12345";
    private static final String SECRET_KEY = "KFZwbiakWw";
    private static final String TRACK_QUERY_ADAPTER_METHOD = "track_query_adapter";
    private static final String VERSION = "v1";
    private static final String QUERY_LOGISTICS_URL = "https://openapi.yto.net.cn:11443/open/track_query_adapter/v1/RVIz3j/open13115939";
    private static final String SUBSCRIBE_ADAPTER_METHOD  = "subscribe_adapter";
    private static final String SUBSCRIBE_ADAPTER_URL = "https://openuat.yto56test.com:6443/open/subscribe_adapter/v1/RVIz3j/TEST";
    private static final Pattern TRANSFER_CENTER_PATTERN = Pattern.compile("(?:到达【|离开【)[^】]*转运中心】");

    /**
     * 查询物流轨迹（自动区分环境）
     * @param waybillNo 运单号（必须以YT开头）
     * @return 响应数据（JSON格式）
     */
    public static JSONObject queryLogistics(String waybillNo) {
        Map<String, String> confParam = getParam(QUERY_LOGISTICS_URL);
        JSONObject param = new JSONObject();
        param.put("NUMBER",waybillNo);
        String data = param.toJSONString()+confParam.get("method")+confParam.get("version");
        String sign = generateSign(data + SECRET_KEY);
        long timestamp = System.currentTimeMillis();
        String requestBody = String.format(
                "{\"timestamp\":\"%d\",\"param\":\"%s\",\"sign\":\"%s\",\"format\":\"JSON\"}",
                timestamp,
                param.toJSONString().replace("\"", "\\\""),  // 处理JSON转义
                sign
        );
        boolean flag=false;
        // 5. 发送请求
        try (HttpResponse response = HttpRequest.post(QUERY_LOGISTICS_URL)
                .header("Content-Type", "application/json;charset=UTF-8")
                .body(requestBody)
                .timeout(5000)
                .execute()) {
            JSONArray steps=new JSONArray();
            if(isJsonArray(response.body())){
                flag=true;
                steps=JSONArray.parseArray(response.body());
            }

            if (response.isOk()) {
                JSONObject result = new JSONObject();
                result.put("steps", steps);
                result.put("succeed", flag);
                return result;
            } else {
                throw new RuntimeException(String.format(
                        "请求失败，状态码: %d，响应: %s",
                        response.getStatus(),
                        response.body()
                ));
            }
        }
    }
    public static boolean isJsonArray(String jsonStr) {
        try {
            JSONArray.parseArray(jsonStr); // 尝试解析为数组
            return true;
        } catch (Exception e1) {
            try {
               JSONObject.parseObject(jsonStr); // 尝试解析为对象
                return false;
            } catch (Exception e2) {
                throw new IllegalArgumentException("既不是 JSON 对象也不是 JSON 数组");
            }
        }
    }

    private static String generateSign(String data) {
        byte[] md5Bytes = DigestUtils.md5(data );
        return Base64.encodeBase64String(md5Bytes);
    }
    public static Map<String,String>getParam(String url){
        Map<String, String> param = new HashMap<>();
        String[] cs = url.split("/");
        param.put("method",cs[cs.length-4]);
        param.put("version",cs[cs.length-3]);
        param.put("customerCode",cs[cs.length-1]);
        return param;
    }

    /**
     * 订阅（自动区分环境）
     * @param waybillNo 运单号（必须以YT开头）
     * @return 响应数据（JSON格式）
     */
    public static JSONObject trackSubSubscribe(String waybillNo) {
        JSONObject logisticsInterface = new JSONObject();
        logisticsInterface.put("clientId", "TEST");
        logisticsInterface.put("waybillNo", "YT100233456");
        // 2. 创建 param 中的 JSON 对象
        JSONObject paramJson = new JSONObject();
        paramJson.put("client_id", "TEST");
        paramJson.put("logistics_interface", logisticsInterface.toJSONString().replace("\"", "\\\"")); // 注意这里要转成字符串
        paramJson.put("msg_type", "online");

        System.out.println(paramJson.toJSONString());
        Map<String, String> confParam = getParam(SUBSCRIBE_ADAPTER_URL);
//        JSONObject param = new JSONObject();
//        JSONObject cParam = new JSONObject();
//        param.put("client_id","TEST");
//        param.put("msg_type","online");
//        cParam.put("clientId","TEST");
//        cParam.put("waybillNo",waybillNo);
//        param.put("logistics_interface",cParam.toJSONString().replace("\"", "\\\""));
        String data = paramJson.toJSONString()+confParam.get("method")+confParam.get("version");
        String sign = generateSign(data + SECRET_KEY);



        long timestamp = System.currentTimeMillis();
        String requestBody = String.format(
                "{\"timestamp\":\"%d\",\"param\":\"%s\",\"sign\":\"%s\",\"format\":\"JSON\"}",
                timestamp,
                paramJson.toJSONString().replace("\"", "\\\""),  // 处理JSON转义
                sign
        );
        // 5. 发送请求
        try (HttpResponse response = HttpRequest.post(SUBSCRIBE_ADAPTER_URL)
                .header("Content-Type", "application/json;charset=UTF-8")
                .body(requestBody)
                .timeout(5000)
                .execute()) {


            if (response.isOk()) {

                return JSONObject.parseObject(response.body());
            } else {
                throw new RuntimeException(String.format(
                        "请求失败，状态码: %d，响应: %s",
                        response.getStatus(),
                        response.body()
                ));
            }
        }
    }
    public static boolean isInTransferCenter(String text) {
        // 正则表达式：匹配两种模式：到达【任意非】字符+转运中心】 或 离开【任意非】字符+转运中心】
        return TRANSFER_CENTER_PATTERN.matcher(text).find();
//        Pattern leavePattern = Pattern.compile("离开【[^】]*转运中心】");
//        Pattern arrivePattern = Pattern.compile("到达【[^】]*转运中心】");
//        Matcher leaveMatcher = leavePattern.matcher(text);
//        Matcher arriveMatcher = arrivePattern.matcher(text);
//        int lastLeaveIndex = -1;
//        int lastArriveIndex = -1;
//        // 查找离开事件最后出现的位置
//        while (leaveMatcher.find()) {
//            lastLeaveIndex = leaveMatcher.start();
//        }
//        // 查找到达事件最后出现的位置
//        while (arriveMatcher.find()) {
//            lastArriveIndex = arriveMatcher.start();
//        }
//        // 如果两个事件都没有，返回false
//        if (lastLeaveIndex == -1 && lastArriveIndex == -1) {
//            return false;
//        }
//        // 比较最后出现的事件：索引值大的就是最后发生的
//        if (lastArriveIndex > lastLeaveIndex) {
//            return true;
//        } else {
//            return false;
//        }
    }
    public static void main(String[] args) {
        System.out.println(trackSubSubscribe("YT100233456"));
//        System.out.println(queryLogistics("YT100233456"));
    }

//    public static void main(String[] args) {
//        System.out.println(queryLogistics("YT7546313422327"));
//    }
    //{"map":{"YT75564634855692":[]},"code":"1001","success":"true","message":"查询结果为空。"}
    // 测试用例
  /*  public static void main(String[] args) {
//        // 测试环境查询
//        JSONObject testResult = queryLogistics("YT2600227881409", true);
//        System.out.println("测试环境结果:\n" + testResult);

        // 生产环境查询（需替换真实运单号）
        // JSONObject prodResult = queryLogistics("YT2600216627986", false);
        // System.out.println("生产环境结果:\n" + prodResult);

        JSONObject entries = queryLogistics("YT2600227881409");
        System.out.println(entries);
    }*/
}